﻿namespace DJLang
{
    public class DJInt : DJBasic<int>, INeg, IAdd, ISub, IMul, IDiv, IEq
    {
        public DJInt(int val) : base(val) { }

        public IDJValue Neg() => new DJInt(-val);

        public IDJValue Add(IDJValue value) => value switch
        {
            DJBasic<int> i => new DJInt(val + i.val),
            DJBasic<float> f => new DJFloat(val + f.val),
            DJRef<string> s => new DJString(val + s.val),
            _ => new DJErr($"Unsupport {this} + {value}")
        };

        public IDJValue Sub(IDJValue value) => value switch
        {
            DJBasic<int> i => new DJInt(val - i.val),
            DJBasic<float> f => new DJFloat(val - f.val),
            _ => new DJErr($"Unsupport {this} - {value}")
        };

        public IDJValue Mul(IDJValue value) => value switch
        {
            DJBasic<int> i => new DJInt(val * i.val),
            DJBasic<float> f => new DJFloat(val * f.val),
            _ => new DJErr($"Unsupport {this} * {value}")
        };

        public IDJValue Div(IDJValue value) => value switch
        {
            DJBasic<int> i => new DJInt(val / i.val),
            DJBasic<float> f => new DJFloat(val / f.val),
            _ => new DJErr($"Unsupport {this} / {value}")
        };

        public IDJValue Eq(IDJValue value) => value switch
        {
            DJBasic<int> i => new DJBasic<bool>(i.val == val),
            DJBasic<float> f => new DJBasic<bool>(f.val == val),
            _ => new DJErr($"Unsupport {this} == {value}")
        };

        public override IDJValue Clone() => new DJInt(val);
        public override string ToString() => $"{val}";                                                                                           
    }

    public class DJFloat : DJBasic<float>, INeg, IAdd, ISub, IMul, IDiv, IEq
    {
        public DJFloat(float val) : base(val) { }

        public IDJValue Neg() => new DJFloat(-val);

        public IDJValue Add(IDJValue value) => value switch
        {
            DJBasic<int> i => new DJFloat(val + i.val),
            DJBasic<float> f => new DJFloat(val + f.val),
            DJRef<string> s => new DJString(val + s.val),
            _ => new DJErr($"Unsupport {this} + {value}")
        };

        public IDJValue Sub(IDJValue value) => value switch
        {
            DJBasic<int> i => new DJFloat(val - i.val),
            DJBasic<float> f => new DJFloat(val - f.val),
            _ => new DJErr($"Unsupport {this} - {value}")
        };

        public IDJValue Mul(IDJValue value) => value switch
        {
            DJBasic<int> i => new DJFloat(val * i.val),
            DJBasic<float> f => new DJFloat(val * f.val),
            _ => new DJErr($"Unsupport {this} * {value}")
        };

        public IDJValue Div(IDJValue value) => value switch
        {
            DJBasic<int> i => new DJFloat(val / i.val),
            DJBasic<float> f => new DJFloat(val / f.val),
            _ => new DJErr($"Unsupport {this} /  {value}")
        };

        public IDJValue Eq(IDJValue value) => value switch
        {
            DJBasic<int> i => new DJBasic<bool>(i.val == val),
            DJBasic<float> f => new DJBasic<bool>(f.val == val),
            _ => new DJErr($"Unsupport {this} == {value}")
        };
        public override IDJValue Clone() => new DJFloat(val);
        public override string ToString() => $"<Float,{val}>";
    }
}
